package com.own.demo.长沙空中路网格子.v2;

import com.alibaba.fastjson.JSONObject;
import com.own.demo.geodemo.ToGeo对角线2;
import com.own.demo.utils.DateUtils;
import com.own.demo.utils.geo.buffer.BufferBase;
import com.own.demo.长沙空中路网格子.BuildingSelect;
import com.own.demo.长沙空中路网格子.Common;
import com.own.demo.长沙空中路网格子.ObstacleVo;
import com.own.demo.长沙空中路网格子.Thread.*;
import lombok.SneakyThrows;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

public class ParentV2 extends Common {

    /**
     * @param geometries 分成格子边界边界数据
     * @param geometry   全量边界
     * @return
     */
    @SneakyThrows
    public static JSONObject goGeoJSONV2(List<Geometry> geometries, Geometry geometry) {
        if (geometries == null) {
            return null;
        }
        int row = geometries.size();
        System.out.println(DateUtils.parseDateToStr(new Date())+"开始解析全局点");
        Date sTime=new Date();
        List<Coordinate> allPoints = Collections.synchronizedList(new ArrayList<>(100000));
        ConcurrentHashMap<String,Long> allMap=new ConcurrentHashMap<>(100000);

        for (int i = 0; i < row; i++) {
            Polygon js = (Polygon) geometries.get(i);
            Point point = js.getCentroid();
            Coordinate coordinate = new Coordinate(point.getX(), point.getY());
            Point point1 = BufferBase.geometryFactory.createPoint(coordinate);
            if (!geometry.intersects(point1)) {
                continue;
            }
            Coordinate[] coordinates = js.getEnvelope().getCoordinates();
            int rowCoordinate=coordinates.length;
            CountDownLatch countDownLatch = new CountDownLatch(rowCoordinate);
            for (int h = 0; h < coordinates.length; h++) {
                Coordinate coordinateA = coordinates[h];
                MainV2.executorService.execute(new ALLThread1(countDownLatch,allMap,coordinateA,allPoints));
            }
            countDownLatch.await();
        }
        allMap.clear();

        System.out.println(DateUtils.parseDateToStr(new Date())+"解析全局点完成，获取所有点时间："+(DateUtils.formatTime(sTime,new Date())));
        sTime=new Date();

        System.out.println(DateUtils.parseDateToStr(new Date())+"去除重复点");
        int allPointsLon = allPoints.size();
        System.out.println("点数量：" + allPoints.size());
        List<Double> lonList = new ArrayList<>(allPointsLon);
        List<Double> latList = new ArrayList<>(allPointsLon);

        for (int i = 0; i < allPointsLon; i++) {
            Coordinate coordinate = allPoints.get(i);
            lonList.add(coordinate.x);
            latList.add(coordinate.y);
        }
        System.out.println("x去重前的数量：" + lonList.size());
        System.out.println("y去重前的数量：" + latList.size());
        lonList = lonList.stream().distinct().collect(Collectors.toList());
        latList = latList.stream().distinct().collect(Collectors.toList());
        System.out.println("x去后前的数量：" + lonList.size());
        System.out.println("y去后前的数量：" + latList.size());

        Map<String, List<Coordinate>> xMap = new LinkedHashMap(10240);
        Map<String, List<Coordinate>> yMap = new LinkedHashMap(10240);
        lonLatAll(xMap,yMap,lonList,latList,allPoints);
        allPoints.clear();
        System.out.println(DateUtils.parseDateToStr(new Date())+"去除重复点完成，获取所有点时间："+(DateUtils.formatTime(sTime,new Date())));
        sTime=new Date();

        //格子点
        List<List<Coordinate>> allXYdata = new ArrayList<>(1026);
        allXYdata.addAll(xMap.values());
        allXYdata.addAll(yMap.values());
        System.out.println(DateUtils.parseDateToStr(new Date())+"解析点完成："+(DateUtils.formatTime(sTime,new Date())));
        sTime=new Date();


        //对角线点
        List<List<Coordinate>> xy = ToGeo对角线2.goGeoJSONV2(geometries, geometry);
        geometries.clear();

        System.out.println(DateUtils.parseDateToStr(new Date())+"画格子："+(DateUtils.formatTime(sTime,new Date())));
        sTime=new Date();

        JSONObject jsonObject= drawInfo(allXYdata,xy);
        System.out.println(DateUtils.parseDateToStr(new Date())+"画格子完成："+(DateUtils.formatTime(sTime,new Date())));

        allXYdata.clear();
        xy.clear();
        return jsonObject;
    }

    private static void lonLatAll( Map<String, List<Coordinate>> xMap,Map<String, List<Coordinate>> yMap,List<Double> lonList,List<Double> latList,List<Coordinate> allPoints ) throws InterruptedException {

        CountDownLatch countDownLatch = new CountDownLatch(2);
        int allPointsLon=allPoints.size();
        MainV2.executorService.execute(new PointLonThread(xMap,countDownLatch,lonList,allPoints,allPointsLon));
        MainV2.executorService.execute(new PointLatThread(yMap,countDownLatch,latList,allPoints,allPointsLon));
        countDownLatch.await();
    }

    private static JSONObject drawInfo( List<List<Coordinate>> allXYdata, List<List<Coordinate>> xy) throws InterruptedException {
        JSONObject  jsonAllData= Common.defaultObjectGsoJSON();
        CountDownLatch countDownLatch = new CountDownLatch(2);
        MainV2.executorService.execute(new DataDrawEvp(allXYdata,countDownLatch,jsonAllData));
        MainV2.executorService.execute(new 对角线DrawEvp(xy,countDownLatch,jsonAllData));
        countDownLatch.await();
        return jsonAllData;
    }

    public static  List<Geometry> geometries(int floor){
        List<Geometry> list=new ArrayList<>();
        List<ObstacleVo> listObstacleVo = BuildingSelect.obstacleVo(floor);
        if (listObstacleVo != null && listObstacleVo.size() > 0) {
            if (listObstacleVo != null && listObstacleVo.size() > 0) {
                int buildRow= listObstacleVo.size();
                for (int i = 0; i < buildRow; i++) {
                    ObstacleVo obstacleVo=  listObstacleVo.get(i);
                    String[] points = obstacleVo.getPoints().split("\\;");
                    int row=points.length;
                    Coordinate[] value = new Coordinate[row];
                    for (int h = 0; h <row ; h++) {
                        String[] arr = points[h].split("\\,");
                        value[h]=new Coordinate(Double.valueOf(arr[0]), Double.valueOf(arr[1]));
                    }
                    list.add(polygonBuffer.geometryCoordinate(value));
                }
            }
        }
        return list;
    }

    public static void setlistObstacleVo(JSONObject jsonObject,int floor, Geometry geometry) {
        List<ObstacleVo> listObstacleVo = BuildingSelect.obstacleVo(floor);
        if (listObstacleVo != null && listObstacleVo.size() > 0) {
            int buildRow= listObstacleVo.size();
            for (int i = 0; i < buildRow; i++) {
                ObstacleVo obstacleVo=  listObstacleVo.get(i);
                String[] points = obstacleVo.getPoints().split("\\;");
                List<Coordinate> value = new ArrayList<>();
                Coordinate[]  coordinates = new Coordinate[points.length];
                for (int h = 0; h < points.length; h++) {
                    String[] arr = points[h].split("\\,");
                    Coordinate coordinate=new Coordinate(Double.valueOf(arr[0]), Double.valueOf(arr[1]));
                    value.add(coordinate);
                    coordinates[h]=coordinate;
                }
                Geometry geometry1=BufferBase.geometryFactory.createPolygon(coordinates);
                if(geometry.within(geometry1) || geometry.intersects(geometry1) ) {
                    jsonObject.getJSONArray("features").addAll(setXYGeo(i, 0, value, "LineString"));
                }
            }
        }
    }
}
